﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace ChatBuddy.Classes.Server
{
    class HttpServer
    {
        protected int Port;
        private TcpListener Listener;
        private bool active_machine = true;

        public static String http_method;
        public static String http_url;
        public static String http_protocol_versionstring;
        public Hashtable httpHeaders = new Hashtable();

        public HttpServer(int port)
        {
            Port = port;
        }

        public class HttpProcessor
        {
            public TcpClient Socket;
            public HttpServer Server;
            private Stream inputStream;
            public StreamWriter outputStream;

            private static int MAX_POST_SIZE = 10*1024*1024;

            public HttpProcessor(TcpClient s, HttpServer server)
            {
                Socket = s;
                Server = server;
            }

            public string StreamLineReader(Stream inputStream)
            {
                var data = "";

                while (true)
                {
                    var nextChar = inputStream.ReadByte();
                    if (nextChar == '\n')
                    {
                        break;
                    }
                    if (nextChar == '\r')
                    {
                        continue;
                    }
                    if (nextChar == -1)
                    {
                        Thread.Sleep(1);
                        continue;
                    }
                    data += Convert.ToChar(nextChar);
                }
                return data;
            }

            public void Process()
            {
                inputStream = new BufferedStream(Socket.GetStream());
                outputStream = new StreamWriter(new BufferedStream(Socket.GetStream()));

                try
                {
                    ParseRequest();
                    ReadHeaders();

                }
                catch (Exception e)
                {
                    // report error
                }
                outputStream.Flush();
                inputStream = null;
                outputStream = null;
                Socket.Close();
            }

            public void ReadHeaders()
            {
                var line = "";
                while ((line == StreamLineReader(inputStream)) != null)
                {
                    if (line.Equals(""))
                    {
                        // received headers
                        return;
                    }

                    var seperator = line.IndexOf(':');
                    if (seperator == -1)
                    {
                        // invalid header
                    }

                    var name = line.Substring(0, seperator);
                    var pos = seperator + 1;
                    while ((pos < line.Length) && (line[pos] == ' '))
                    {
                        pos++; // removes spaces
                    }

                    var value = line.Substring(pos, line.Length - pos);
                }
            }

            public void ParseRequest()
            {
                var request = StreamLineReader(inputStream);
                var tokens = request.Split(' ');
                if (tokens.Length != 3)
                {
                    // invalid request
                }

                http_method = tokens[0].ToUpper();
                http_url = tokens[1];
                http_protocol_versionstring = tokens[2];
            }

        }

        public void Listen()
        {
            Listener = new TcpListener(Port);
            Listener.Start();

            while (active_machine)
            {
                var s = Listener.AcceptTcpClient();
                var processor = new HttpProcessor(s, this);
                var thread = new Thread(processor.Process);
            }
        }

    }
}
